<?php

namespace App\Http\Controllers\Admin;

use App\Services\Tools\Export;
use App\Exceptions\BasicException;
use App\Http\Controllers\BaseController;
use App\Response\Response;
use App\Services\Tools\ExportService;
use App\Services\Tools\HelperService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class StatisticsController extends BaseController
{
    /**
     * @api {Get} /statistic/index 平台所有数据汇总统计
     * @apiGroup 补充接口-订单管理
     * @apiParam {String} start_date 开始日期
     * @apiParam {String} end_date 结束日期
     * @apiParam {String} nickname 用户昵称
     * @apiParam {Int} user_no 用户编号
     * @apiParam {Int} mobile 用户手机号
     * @apiSuccessExample {json} Response-Example
     *{
     * "code": 200,
     * "data": {
     * "grades": [
     * {
     * "id": 1,
     * "grade": "1"
     * },
     * {
     * "id": 2,
     * "grade": "2"
     * }
     * ],
     * "serial_total": 34976416939,
     * "user_reg_total": 96212,
     * "recharge_total": "581.82",
     * "withdraw_total": "47555695.78",
     * "withdraw_check_total": "47555695.78",//待审核提现的
     * "everyday_recharge_total": [
     * {
     * "recharge_money": "0.02", 充值金额
     * "withdraw_money": "200.00" 提现金额
     * "withdraw_money_check": "200.00" //待审核金额
     * "withdraw_money_audit": "200.00"
     * "date": "2021-05-07" 日期
     * }
     * ]
     * }
     * }
     */
    public function index(Request $request)
    {
        $startDate = $request->start_date;
        $endDate = $request->end_date;
        $nickname = $request->nickname;
        $userNo = $request->user_no;
        $mobile = $request->mobile;

        if ($startDate) {
            $startTime = strtotime($startDate . ' 0:0:0');
        } else {
            $startTime = 0;
        }
        if ($endDate) {
            $endTime = strtotime($endDate . ' 23:59:59');
        } else {
            $endTime = 0;
        }

        //平台总流水
        $serial1 = app('model_give_gift_day')->where('date', '<=', date('Y-m-d'))->sum('total');
        $serial2 = app('model_give_gift')->where('add_time', '>=', strtotime(date('Y-m-d 0:0:0')))->sum('total_price');
        $serialTotal = $serial1 + $serial2;

        //平台总注册人数
        $userRegTotal = app('model_user')
            ->where(function ($query) use ($startTime, $endTime) {
                if ($startTime) {
                    $query->where('register_time', '>=', $startTime);
                }
                if ($endTime) {
                    $query->where('register_time', '<=', $endTime);
                }
            })->count();

        //用户总充值
        $userWhere = [];
        if ($nickname) {
            $userWhere[] = ['ud.nickname', '=', $nickname];
        }
        if ($userNo) {
            $userWhere[] = ['ud.user_code', '=', $userNo];
        }
        if ($mobile) {
            $userWhere[] = ['u.mobile', '=', $mobile];
        }

        $userIdWhere = [];
        if ($userWhere) {
            $user = app('model_user_data')->from('ln_user_data as ud')
                ->leftJoin('ln_user as u', 'ud.user_id', '=', 'u.user_id')
                ->select('ud.user_id')
                ->where($userWhere)
                ->where('u.deleted', 0)
                ->first();
            if ($user) {
                $userIdWhere = ['user_id' => $user->user_id];
            } else {
                $userIdWhere = ['user_id' => 0];
            }
        }

        //充值总计
        $rechargeTotal = app('model_user_recharge')
            ->where('status', 2)
            ->where('type', '<>', 3)
            ->where($userIdWhere)
            ->where(function ($query) use ($startTime, $endTime) {
                if ($startTime) {
                    $query->where('pay_time', '>=', $startTime);
                }
                if ($endTime) {
                    $query->where('pay_time', '<=', $endTime);
                }
            })->sum('money');

        //申请提现总金额
        $apply = app('model_user_withdraw')
            ->where($userIdWhere)
            ->where(function ($query) use ($startTime, $endTime) {
                if ($startTime) {
                    $query->where('add_time', '>=', $startTime);
                }
                if ($endTime) {
                    $query->where('add_time', '<=', $endTime);
                }
            })->sum('money');

        //业务后台拒绝金额
        $platformRefuse = app('model_user_withdraw')
            ->where($userIdWhere)
            ->where('platform_status',3)
            ->where(function ($query) use ($startTime, $endTime) {
                if ($startTime) {
                    $query->where('audit_time', '>=', $startTime);
                }
                if ($endTime) {
                    $query->where('audit_time', '<=', $endTime);
                }
            })->sum('money');

        //业务后台同意金额(申请打款金额)
        $platformPass = app('model_user_withdraw')
            ->where($userIdWhere)
            ->where('platform_status',2)
            ->where(function ($query) use ($startTime, $endTime) {
                if ($startTime) {
                    $query->where('audit_time', '>=', $startTime);
                }
                if ($endTime) {
                    $query->where('audit_time', '<=', $endTime);
                }
            })->sum('money');

        //财务拒绝金额
        $financeRefuse = app('model_user_withdraw')
            ->where($userIdWhere)
            ->where('status',3)
            ->where(function ($query) use ($startTime, $endTime) {
                if ($startTime) {
                    $query->where('operate_time', '>=', $startTime);
                }
                if ($endTime) {
                    $query->where('operate_time', '<=', $endTime);
                }
            })->sum('money');

        //用户总提现金额 已经提现的
        $financePass = app('model_user_withdraw')
            ->where('status', 2)
            ->where('platform_status',2)
            ->where($userIdWhere)
            ->where(function ($query) use ($startTime, $endTime) {
                if ($startTime) {
                    $query->where('operate_time', '>=', $startTime);
                }
                if ($endTime) {
                    $query->where('operate_time', '<=', $endTime);
                }
            })->sum('money');


        //每日充值统计
        $everydayRechargeTotal = $this->everydaySerialTotal($startDate, $endDate);

        return Response::sendData([
            'serial_total'            => round($serialTotal,2),
            'user_reg_total'          => round($userRegTotal,2),
            'recharge_total'          => round($rechargeTotal,2),
            'apply_total'             => round($apply,2),            //申请提现金额
            'platform_refuse'         => round($platformRefuse,2),   //运营拒绝金额
            'withdraw_apply'          => round($platformPass,2),     //v财务待审核金额
            'finance_refuse'          => round($financeRefuse,2),    //财务拒绝金额
            'finance_pass'            => round($financePass,2),      //提现成功金额
            'everyday_recharge_total' => $everydayRechargeTotal,                //列表数据
        ]);
    }

    //最近N天每日流水统计
    private function everydaySerialTotal($startDate, $endDate)
    {
        //everyday_recharge_total
        $days = 30;
        if (empty($startDate)) {
            $startDate = date('Y-m-d', strtotime("-$days day"));
        }
        if (empty($endDate)) {
            $endDate = date('Y-m-d');
        }
        $timeRange = [strtotime($startDate . ' 0:0:0'), strtotime($endDate . ' 23:59:59')];

        $everyRechargeTotal = app('model_user_recharge')
            ->select(DB::raw("from_unixtime(pay_time, '%Y-%m-%d') as pay_date, sum(money) as recharge_money"))
            ->where('status', 2)
            ->where('type', '<>', 3)
            ->whereBetween('pay_time', $timeRange)
            ->groupBy('pay_date')
            ->pluck('recharge_money', 'pay_date')->toArray();

        //申请提现金额
        $apply = app('model_user_withdraw')
            ->select(DB::raw("from_unixtime(add_time, '%Y-%m-%d') as ddate, sum(money) as withdraw_money"))
            ->whereBetween('add_time', $timeRange)
            ->groupBy('ddate')
            ->pluck('withdraw_money', 'ddate')->toArray();
        //运营拒绝金额
        $platformRefuse = app('model_user_withdraw')
        ->select(DB::raw("from_unixtime(audit_time, '%Y-%m-%d') as ddate, sum(money) as withdraw_money"))
            ->where('platform_status', 3)
            ->whereBetween('audit_time', $timeRange)
            ->groupBy('ddate')
            ->pluck('withdraw_money', 'ddate')->toArray();

        //运营通过金额
        $platformPass = app('model_user_withdraw')
        ->select(DB::raw("from_unixtime(audit_time, '%Y-%m-%d') as ddate, sum(money) as withdraw_money"))
            ->where('platform_status', 2)
            ->whereBetween('audit_time', $timeRange)
            ->groupBy('ddate')
            ->pluck('withdraw_money', 'ddate')->toArray();

        //财务拒绝金额
        $financeRefuse = app('model_user_withdraw')
        ->select(DB::raw("from_unixtime(operate_time, '%Y-%m-%d') as ddate, sum(money) as withdraw_money"))
            ->where('status', 3)
            ->whereBetween('operate_time', $timeRange)
            ->groupBy('ddate')
            ->pluck('withdraw_money', 'ddate')->toArray();
        //财务通过金额
        $financePass = app('model_user_withdraw')
            ->select(DB::raw("from_unixtime(operate_time, '%Y-%m-%d') as ddate, sum(money) as withdraw_money"))
            ->where('status', 2)
            ->where('platform_status',2)
            ->whereBetween('operate_time', $timeRange)
            ->groupBy('ddate')
            ->pluck('withdraw_money', 'ddate')->toArray();


        $dates = $this->getRecentlyDates($startDate, $endDate);
        $everydayTotal = [];
        foreach ($dates as $date) {
            $everydayTotal[] = [
                'date'                 => $date,
                'recharge_money'       => $everyRechargeTotal[$date] ?? 0,
                'apply'                => $apply[$date] ??  0,
                'platform_refuse'      => $platformRefuse[$date] ?? 0,
                'platform_pass'        => $platformPass[$date] ?? 0,
                'finance_refuse'       => $financeRefuse[$date] ?? 0,
                'finance_pass'         => $financePass[$date] ?? 0,
            ];
        }
        return $everydayTotal;
    }

    private function getRecentlyDates($startDate, $endDate)
    {
        if ($endDate < $startDate) {
            return [];
        }
        $dates = [$endDate];

        while (true) {
            $endDate = date('Y-m-d', strtotime("$endDate -1 day"));
            if ($endDate >= $startDate) {
                $dates[] = $endDate;
            } else {
                break;
            }
        }

        return $dates;
    }
    //
    //    /**
    //     * 最近N天待审核提现统计 默认前30天
    //     *
    //     * @param $startDate 开始时间 Y-m-d 格式
    //     * @param $endDate 结束时间
    //     */
    //    private function getWithdrawDates($startDate, $endDate)
    //    {
    //        $days = 30;
    //        if (empty($startDate)) {
    //            $startDate = date('Y-m-d', strtotime("-$days day"));
    //        }
    //        if (empty($endDate)) {
    //            $endDate = date('Y-m-d');
    //        }
    //        $timeRange = [strtotime($startDate . ' 0:0:0'), strtotime($endDate . ' 23:59:59')];
    //
    //        app('model_user_withdraw')
    //            ->whereBetween('audit_time', $timeRange)
    //            ->where('')
    //    }

    /**
     * @api {Get} /statistic/userGradeExport 每日流水统计
     * @apiGroup 补充接口-每日流水统计
     * @apiParam {String} start_date 开始日期
     * @apiParam {String} end_date 结束日期
     * @apiSuccessExample {json} Response-Example
     * {
     * "code": 200,
     * "data": {
     * "download_url": "http://yutangyuyin1.oss-cn-hangzhou.aliyuncs.com/data_excel/20210922101447260订单管理数据统计.xls"
     * }
     * }
     */
    public function userGradeExport(Request $request)
    {
        $startDate = $request->start_date;
        $endDate = $request->end_date;

        //每日充值统计
        $everydayRechargeTotal = $this->everydaySerialTotal($startDate, $endDate);

        $list = [];
        foreach ($everydayRechargeTotal as $key => $value) {
            $list[$key][0] = $value['date'];
            $list[$key][1] = $value['recharge_money'] == 0 ? "0" : $value['recharge_money'];
            $list[$key][2] = $value['apply'] == 0 ? "0" : $value['apply'];
            $list[$key][3] = $value['platform_refuse'] == 0 ? "0" : $value['platform_refuse'];
            $list[$key][4] = $value['platform_pass'] == 0 ? "0" : $value['platform_pass'];
            $list[$key][5] = $value['finance_refuse'] == 0 ? "0" : $value['finance_refuse'];
            $list[$key][6] = $value['finance_pass'] == 0 ? "0" : $value['finance_pass'];
        }

        $headings = [
            '日期',
            '充值金额',
            '申请提现金额',
            '运营拒绝金额',
            '申请打款金额',
            '财务拒绝金额',
            '财务打款金额'
        ];

        //每日流水统计
        return app('repo_export')->export(22, $request->all(), $headings, $list);

        //        $downloadUrl = Export::exportUsePhpOffice('game_keep_data', $fields, $res);
        //        app('model_admin_export_log')->add(21, $data, $downloadUrl);
        //        return Response::sendData(['game_keep_data' => $downloadUrl]);

        //        $filename = '/data_excel/' . date('YmdHis') . mt_rand(100, 999) . '订单管理数据统计.xls';
        //        $res = app('excel')->store(new ExportService($list, $headings), $filename, 'oss', 'Xls');
        //
        //        if (!$res) {
        //            throw new BasicException(90030);
        //        }
        //
        //        return Response::sendData(
        //            [
        //                "download_url" => 'http://' . env('OSS_BUCKET') . '.' . env('OSS_ENDPOINT') . $filename,
        //            ]
        //        );
    }

    /**
     * @api {Get} /statistic/keep/game 留存统计-各个游戏留存数据
     * @apiGroup 留存统计
     * @apiParam {int} page
     * @apiParam {int} page_size
     * @apiParam {int} type 1按小时统计 2 按天统计
     * @apiParam {int} start_time 时间筛选 开始时间 时间戳
     * @apiParam {int} end_time 时间筛选 结束时间 时间戳
     * @apiSuccessExample {json} Response-Example
     * {
     * "code": 200,
     * "data": {
     * "total": 0,
     * "current_page": 1,
     * "last_page": 1,
     * "list": [
     * {
     * "start_time": 1632308400,
     * "tree": {
     * "add": "1.00",//投入
     * "sum": "12.00",//产出
     * "gain": -11.00//盈利
     * },
     * "hu": {
     * "add": "0.00",
     * "sum": "0.00",
     * "gain": "+0.00"
     * },
     * "gift": {
     * "add": "0.00",
     * "sum": "0.00",
     * "gain": "+0.00"
     * },
     * "candy": {
     * "add": "0.00",
     * "sum": "0.00",
     * "gain": "+0.00"
     * }
     * },
     * ]
     * }
     * }
     */
    public function accountCheck(Request $request)
    {
        $data = $request->only(['page', 'page_size', 'type', 'start_time', 'end_time']);

        $va = app('validator')->make($data, [
            'type'       => 'required|integer|in:1,2',
            'page'       => 'integer|min:1',
            'page_size'  => 'integer|max:50|min:1',
            'start_time' => 'integer|min:0',
            'end_time'   => 'integer|min:0',
        ]);
        if ((isset($data['start_time']) && !isset($data['end_time'])) || (!isset($data['start_time']) && isset($data['end_time']))) {
            throw  new BasicException(10001, '开始时间与结束时间应该同时填活不填');
        }
        if ($va->fails()) {
            throw  new BasicException(10001, $va->errors()->first());
        }

        $data['page'] = $data['page'] ?? 1;
        $data['page_size'] = $data['page_size'] ?? 20;
        $data['type'] = $data['type'] ?? 1;
        $data['start_time'] = $data['start_time'] ?? 0;
        $data['end_time'] = $data['end_time'] ?? 0;

        $res = app('repo_account_check')->hourKeepPrice($data['type'], $data['page'], $data['page_size'], $data['start_time'], $data['end_time']);

        return Response::sendData($res);
    }

    //按天统计购买总金额

    /**
     * @api {Get} /statistic/keep/mallcate 按天统计购买总金额
     * @apiGroup 留存统计
     * @apiParam {int} page
     * @apiParam {int} page_size
     * @apiParam {int} start_time 时间筛选 开始时间 时间戳
     * @apiParam {int} end_time 时间筛选 结束时间 时间戳
     * @apiSuccessExample {json} Response-Example
     * {
     * "code": 200,
     * "data": {
     * "total": 0,
     * "current_page": 1,
     * "last_page": 1,
     * "list": [
     * {
     * "start_time": 1632153600,
     * "0": {
     * "cate_id": 1,
     * "money": "10000.00"
     * },
     * "1": {
     * "cate_id": 2,
     * "money": "1.00"
     * },
     * "2": {
     * "cate_id": 4,
     * "money": "0.00"
     * },
     * "3": {
     * "cate_id": 99,
     * "money": "0.00"
     * }
     * },
     * {
     * "start_time": 1632326400,
     * "0": {
     * "cate_id": -1,
     * "money": "0.00"
     * }
     * }
     * ]
     * }
     * }
     */
    public function fordayMallOrder(Request $request)
    {
        $data = $request->only(['page', 'page_size', 'start_time', 'end_time']);

        $va = app('validator')->make($data, [
            'page'       => 'integer|min:1',
            'page_size'  => 'integer|max:50|min:1',
            'start_time' => 'integer|min:0',
            'end_time'   => 'integer|min:0',
        ]);
        $data['page'] = $data['page'] ?? 1;
        $data['page_size'] = $data['page_size'] ?? 20;
        $data['start_time'] = $data['start_time'] ?? 0;
        $data['end_time'] = $data['end_time'] ?? 0;
        if ($va->fails()) {
            throw  new BasicException(10001, $va->errors()->first());
        }
        $res = app('repo_account_check')->forDayMallCate($data['page'], $data['page_size'], $data['start_time'], $data['end_time']);

        return Response::sendData($res);
    }

    //需要统计的商品分类

    /**
     * @api {Get} /statistic/cate 需要统计的商品分类
     * @apiGroup 留存统计
     * @apiSuccessExample {json} Response-Example
     * {
     * "code": 200,
     * "data": [
     * {
     * "id": 1,
     * "title": "挂件"
     * },
     * {
     * "id": 2,
     * "title": "坐骑"
     * },
     * {
     * "id": 4,
     * "title": "入场特效"
     * },
     * {
     * "id": 7,
     * "title": "套装"
     * },
     * {
     * "id": 8,
     * "title": "靓号"
     * },
     * {
     * "id": 23,
     * "title": "聊天气泡"
     * },
     * {
     * "id": 24,
     * "title": "公屏气泡"
     * },
     * {
     * "id": 25,
     * "title": "声波"
     * },
     * {
     * "id": 26,
     * "title": "全服广播"
     * },
     * {
     * "id": 27,
     * "title": "昵称挂件"
     * },
     * {
     * "id": 33,
     * "title": "昵称特效"
     * },
     * {
     * "id": -1,
     * "title": "全部"
     * }
     * ]
     * }
     */
    public function mallCate()
    {
        //几个重要的商品分类
        $category_list = app('model_mall_categories')->select('id', 'title')->whereIn('id', [1, 2, 4, 7, 8, 23, 24, 25, 26, 27, 33])->get()->toArray();
        $category_list[] = ['id' => -1, 'title' => '全部'];

        return Response::sendData($category_list);
    }


    /**
     * @api {get} /statistic/keep/game/excel     游戏部分 每日留存导出
     * @apiVersion 0.1.0
     * @apiName  游戏部分 每日留存导出
     * @apiGroup 留存统计
     * @apiParam {int} type 1按小时统计 2 按天统计
     * @apiParam {int} start_time 时间筛选 开始时间 时间戳
     * @apiParam {int} end_time 时间筛选 结束时间 时间戳
     * @apiSuccessExample 成功响应
     * {
     * "code": 200,
     * "data": {
     * "download_url": "asdasdasd.com"
     * }
     */
    public function accountChecktoXlsl(Request $request)
    {
        $data = $request->only(['type', 'start_time', 'end_time']);

        $va = app('validator')->make($data, [
            'type'       => 'required|integer|in:1,2',
            'start_time' => 'integer|min:0',
            'end_time'   => 'integer|min:0',
        ]);

        $data['type'] = $data['type'] ?? 1;
        $data['start_time'] = $data['start_time'] ?? 0;
        $data['end_time'] = $data['end_time'] ?? 0;
        if ((isset($data['start_time']) && !isset($data['end_time'])) || (!isset($data['start_time']) && isset($data['end_time']))) {
            throw  new BasicException(10001, '开始时间与结束时间应该同时填活不填');
        }
        if ($va->fails()) {
            throw  new BasicException(10001, $va->errors()->first());
        }
        $res = app('repo_account_check')->hourKeepPriceAllData($data['type'], $data['start_time'], $data['end_time']);


        $fields = [
            ['field' => 'start_time', 'header' => '时间', 'width' => '18'],

            ['field' => 'candy.add', 'header' => '抢糖果投入', 'width' => '18'],
            ['field' => 'candy.sum', 'header' => '抢糖果产出', 'width' => '18'],
            ['field' => 'candy.gain', 'header' => '抢糖果盈亏', 'width' => '18'],

            ['field' => 'gift.add', 'header' => '盲盒礼物投入', 'width' => '18'],
            ['field' => 'gift.sum', 'header' => '盲盒礼物产出', 'width' => '18'],
            ['field' => 'gift.gain', 'header' => '盲盒礼物盈亏', 'width' => '18'],

            ['field' => 'hu.add', 'header' => '霍克游戏投入', 'width' => '18'],
            ['field' => 'hu.sum', 'header' => '霍克游戏产出', 'width' => '18'],
            ['field' => 'hu.gain', 'header' => '霍克游戏盈亏', 'width' => '18'],

            ['field' => 'tree.add', 'header' => '许愿树投入', 'width' => '18'],
            ['field' => 'tree.sum', 'header' => '许愿树产出', 'width' => '18'],
            ['field' => 'tree.gain', 'header' => '许愿树盈亏', 'width' => '18'],

            ['field' => 'tree_common.add', 'header' => '许愿树公池投入', 'width' => '18'],
            ['field' => 'tree_common.sum', 'header' => '许愿树公池产出', 'width' => '18'],
            ['field' => 'tree_common.gain', 'header' => '许愿树公池盈亏', 'width' => '18'],

            ['field' => 'star.add', 'header' => '星之许愿池投入', 'width' => '18'],
            ['field' => 'star.sum', 'header' => '星之许愿池产出', 'width' => '18'],
            ['field' => 'star.gain', 'header' => '星之许愿池盈亏', 'width' => '18'],
        ];



        $downloadUrl = Export::exportUsePhpOffice('game_keep_data', $fields, $res);
        app('model_admin_export_log')->add(21, $data, $downloadUrl);

        return Response::sendData(['game_keep_data' => $downloadUrl]);
    }


    /**
     * @api {get} /statistic/keep/mallcate/excel   商城留存数据导出
     * @apiVersion 0.1.0
     * @apiName  商城留存数据导出
     * @apiGroup 留存统计
     * @apiParam {int} start_time 时间筛选 开始时间 时间戳
     * @apiParam {int} end_time 时间筛选 结束时间 时间戳
     * @apiSuccessExample 成功响应
     * {
     * "code": 200,
     * "data": {
     * "download_url": "asdasdasd.com"
     * }
     */
    public function fordayMallOrderToExcel(Request $request)
    {
        $data = $request->only(['start_time', 'end_time']);

        $va = app('validator')->make($data, [

            'start_time' => 'integer|min:0',
            'end_time'   => 'integer|min:0',
        ]);

        $data['start_time'] = $data['start_time'] ?? 0;
        $data['end_time'] = $data['end_time'] ?? 0;
        if ($va->fails()) {
            throw  new BasicException(10001, $va->errors()->first());
        }
        $res = app('repo_account_check')->forDayMallCateAllDate($data['start_time'], $data['end_time']);
        $fields = [];
        foreach ($res['cateTitle'] as $key => $value) {
            $fields[] = ['field' => $key, 'header' => $value, 'width' => '18'];
        }


        $downloadUrl = Export::exportUsePhpOffice('mall_stat', $fields, $res['stat']);
        app('model_admin_export_log')->add(18, $data, $downloadUrl);

        return Response::sendData(['game_keep_data' => $downloadUrl]);
    }

}
